package com.cdty.chess.util;

import com.cdty.chess.model.CosProperties;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.DeleteObjectsRequest;
import com.qcloud.cos.model.ListObjectsRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 腾讯云COS文件操作工具类
 */
@Component
@RequiredArgsConstructor
public class CosFileUtils implements FileUtils {

    @Autowired
    private final COSClient cosClient;

    @Autowired
    private final CosProperties cosProperties;
    
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    private static final String DELIMITER = "/";

    @Override
    public String uploadFile(InputStream inputStream, String fileName, String contentType) {
        var key = generateFileKey(fileName);
        var metadata = new ObjectMetadata();
        metadata.setContentType(contentType);
        
        var putRequest = new PutObjectRequest(cosProperties.getBucket(), key, inputStream, metadata);
        cosClient.putObject(putRequest);
        
        return key;
    }

    @Override
    public List<String> uploadFiles(List<FileUploadRequest> files) {
        return files.stream()
                .map(file -> {
                    var key = generateFileKey(file.fileName());
                    var metadata = new ObjectMetadata();
                    metadata.setContentType(file.contentType());
                    metadata.setContentLength(file.size());
                    
                    var putRequest = new PutObjectRequest(
                        cosProperties.getBucket(),
                        key,
                        file.inputStream(),
                        metadata
                    );
                    cosClient.putObject(putRequest);
                    return key;
                })
                .collect(Collectors.toList());
    }

    @Override
    public void deleteFile(String fileUrl) {
        var key = getFileKeyFromUrl(fileUrl);
        
        // 如果是目录（以 / 结尾），则递归删除目录下的所有内容
        if (key.endsWith(DELIMITER)) {
            var request = new ListObjectsRequest();
            request.setBucketName(cosProperties.getBucket());
            request.setPrefix(key);
            request.setMaxKeys(1000);
            
            var result = cosClient.listObjects(request);
            
            // 删除目录下的所有文件和子目录
            var objectsToDelete = result.getObjectSummaries().stream()
                    .map(obj -> obj.getKey())
                    .collect(Collectors.toList());
            
            // 如果目录不为空，批量删除所有对象
            if (!objectsToDelete.isEmpty()) {
                var deleteRequest = new DeleteObjectsRequest(cosProperties.getBucket());
                var keys = objectsToDelete.stream()
                        .map(k -> new DeleteObjectsRequest.KeyVersion(k))
                        .collect(Collectors.toList());
                deleteRequest.setKeys(keys);
                cosClient.deleteObjects(deleteRequest);
            }
        }
        
        // 删除文件或空目录
        cosClient.deleteObject(cosProperties.getBucket(), key);
    }

    @Override
    public void deleteFiles(List<String> fileUrls) {
        // 分别处理普通文件和目录
        var normalFiles = new ArrayList<String>();
        var directories = new ArrayList<String>();
        
        for (var url : fileUrls) {
            var key = getFileKeyFromUrl(url);
            if (key.endsWith(DELIMITER)) {
                directories.add(url);
            } else {
                normalFiles.add(key);
            }
        }
        
        // 先删除普通文件
        if (!normalFiles.isEmpty()) {
            var deleteRequest = new DeleteObjectsRequest(cosProperties.getBucket());
            var keys = normalFiles.stream()
                    .map(k -> new DeleteObjectsRequest.KeyVersion(k))
                    .collect(Collectors.toList());
            deleteRequest.setKeys(keys);
            cosClient.deleteObjects(deleteRequest);
        }
        
        // 再删除目录（递归删除）
        directories.forEach(this::deleteFile);
    }

    @Override
    public CosFileList listFiles(String prefix) {
        // 创建请求对象
        var request = new ListObjectsRequest();
        request.setBucketName(cosProperties.getBucket());
        request.setDelimiter(DELIMITER);
        request.setMaxKeys(1000);
        
        // 处理前缀，确保以 / 结尾
        if (StringUtils.hasText(prefix)) {
            if (!prefix.endsWith(DELIMITER)) {
                prefix += DELIMITER;
            }
            request.setPrefix(prefix);
        }
        
        var result = cosClient.listObjects(request);
        
        // 获取文件列表，过滤掉目录（以 / 结尾的对象）
        var files = result.getObjectSummaries().stream()
                .filter(obj -> !obj.getKey().endsWith(DELIMITER)) // 过滤掉目录
                .map(obj -> new CosFileInfo(
                    obj.getKey(),
                    cosProperties.getDomain() + "/" + obj.getKey(),
                    obj.getSize(),
                    LocalDateTime.ofInstant(obj.getLastModified().toInstant(),
                            ZoneId.systemDefault()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                ))
                .collect(Collectors.toList());
        
        // 获取目录列表
        var directories = result.getCommonPrefixes();
        
        return new CosFileList(files, directories);
    }
    
    @Override
    public void createDirectory(String directory) {
        if (StringUtils.hasText(directory)) {
            throw new IllegalArgumentException("目录路径不能为空");
        }
        
        // 确保目录以 / 结尾
        if (!directory.endsWith(DELIMITER)) {
            directory += DELIMITER;
        }
        
        // 创建一个空对象作为目录标记
        var metadata = new ObjectMetadata();
        metadata.setContentLength(0);
        
        var putRequest = new PutObjectRequest(
            cosProperties.getBucket(),
            directory,
            new ByteArrayInputStream(new byte[0]),
            metadata
        );
        
        cosClient.putObject(putRequest);
    }

    private String generateFileKey(String fileName) {
        var extension = fileName.substring(fileName.lastIndexOf("."));
        var nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
        
        // 添加日期后缀
        var date = LocalDateTime.now().format(DATE_FORMATTER);
        
        return nameWithoutExt + "_" + date + extension;
    }

    private String getFileKeyFromUrl(String fileUrl) {
        return fileUrl.replace(cosProperties.getDomain() + "/", "");
    }
}